<template>
  <div class="xpage">
    <div class="left_obj">
      <div v-for="item in deviceList" :key="item.label" draggable="true" @dragstart="handleDragStart($event, item)"
        class="draggable-item">
        <img style="width:50px;height:50px" :src="type_icon_map[item.type]" alt="">
        <div>
          {{ item.label }}
        </div>
      </div>
    </div>

    <div ref="container" id="container" class="my_container" @dragover="handleDragOver" @drop="handleDrop"
      @contextmenu.prevent></div>

    <a-modal v-model:visible="modalVisible" :title="`编辑设备 - ${selectedDevice?.data?.label || ''}`" @ok="handleModalOk"
      @cancel="handleModalCancel">
      <a-form :model="deviceForm" layout="vertical">
        <a-form-item v-for="param in deviceParams" :key="param.key" :label="param.label">
          <a-input v-model:value="deviceForm[param.key]" :suffix="param.unit || ''" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import { Graph } from '@antv/x6';
import { Modal as AModal, Form as AForm, FormItem as AFormItem, Input as AInput } from 'ant-design-vue';

const container = ref(null);
const graph = ref(null);
const draggedItem = ref(null);
const modalVisible = ref(false);
const selectedDevice = ref(null);

// 设备参数配置
const deviceParamsConfig = {
  meter: [
    { key: 'power', label: '功率', unit: 'kW', defaultValue: '10' },
    { key: 'voltage', label: '电压', unit: 'V', defaultValue: '220' }
  ],
  pcs: [
    { key: 'capacity', label: '容量', unit: 'kWh', defaultValue: '50' },
    { key: 'efficiency', label: '效率', unit: '%', defaultValue: '95' }
  ],
  bms: [
    { key: 'cells', label: '电池数量', unit: '节', defaultValue: '16' },
    { key: 'temperature', label: '温度', unit: '°C', defaultValue: '25' }
  ]
};
// 在 JS 顶部先导入
import pcsIcon from '@/assets/svg_icon/icon01.svg'
import bmsIcon from '@/assets/svg_icon/icon02.svg'
import meterIcon from '@/assets/svg_icon/icon03.svg'

// 设备列表
let type_icon_map = {
  pcs: pcsIcon,
  bms: bmsIcon,
  meter: meterIcon,
}
const deviceList = [
  { label: 'PCS', type: 'pcs' },
  { label: 'BMS', type: 'bms' },
  { label: '电表1', type: 'meter' }
];

// 表单数据
const deviceForm = reactive({});
const deviceParams = ref([]);

// 连线状态
const connectingState = reactive({
  isConnecting: false,
  sourceNode: null,
  edge: null
});

// 端口配置
const ports = {
  groups: {
    top: { position: 'top', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    right: { position: 'right', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    bottom: { position: 'bottom', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    left: { position: 'left', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
  },
  items: [
    { group: 'top' },
    { group: 'right' },
    { group: 'bottom' },
    { group: 'left' },
  ],
};

// 注册自定义节点
Graph.registerNode('device-node', {
  inherit: 'rect',
  markup: [
    { tagName: 'rect', selector: 'body' },
    { tagName: 'image', selector: 'image' },
    { tagName: 'text', selector: 'text' },
    { tagName: 'text', selector: 'params' }
  ],
  attrs: {
    body: {
      stroke: '#5F95FF',
      strokeWidth: 1,
      fill: '#EFF4FF',
      rx: 6,
      ry: 6
    },
    image: {
      'xlink:href': 'https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg',
      width: 40,
      height: 40,
      x: 10,
      y: 10
    },
    text: {
      text: '设备',
      fontSize: 12,
      fill: '#262626',
      refX: 0.5,
      refY: '100%',
      y: -10,
      textAnchor: 'middle'
    },
    params: {
      text: '',
      fontSize: 10,
      fill: '#666',
      refX: 0.5,
      refY: '100%',
      y: 5,
      textAnchor: 'middle'
    }
  },
  ports: { ...ports },
}, true);

// 注册自定义连线
Graph.registerEdge('device-connection', {
  inherit: 'edge',
  attrs: {
    line: {
      stroke: '#1890ff',
      strokeWidth: 2,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8,
      },
    },
  },
  zIndex: 0,
}, true);

// 创建设备节点
const createDeviceNode = (graph, item, position) => {
  const params = {};
  const paramsConfig = deviceParamsConfig[item.type] || [];
  paramsConfig.forEach(param => {
    params[param.key] = param.defaultValue;
  });

  return graph.createNode({
    shape: 'device-node',
    width: 120,
    height: 100,
    x: position.x,
    y: position.y,
    attrs: {
      text: { text: item.label },
      params: {
        text: paramsConfig.map(p => `${p.label}: ${params[p.key]}${p.unit}`).join('\n')
      }
    },
    data: {
      type: item.type,
      label: item.label,
      params: params
    }
  });
};

// 更新节点参数显示
const updateNodeParamsDisplay = (node) => {
  const paramsConfig = deviceParamsConfig[node.data.type] || [];
  node.attr('params/text',
    paramsConfig.map(p => `${p.label}: ${node.data.params[p.key]}${p.unit}`).join('\n'));
};

// 拖拽开始
const handleDragStart = (e, item) => {
  draggedItem.value = item;
  e.dataTransfer.setData('text/plain', item.label);
  e.dataTransfer.effectAllowed = 'copy';
};

// 拖拽经过画布
const handleDragOver = (e) => {
  e.preventDefault();
  e.dataTransfer.dropEffect = 'copy';
};

// 拖拽放置
const handleDrop = (e) => {
  e.preventDefault();
  if (!draggedItem.value || !graph.value) return;

  const point = graph.value.clientToLocal(e.clientX, e.clientY);
  const node = createDeviceNode(graph.value, draggedItem.value, point);
  graph.value.addNode(node);

  draggedItem.value = null;
};

// 显示编辑模态框
const showEditModal = (node) => {
  selectedDevice.value = node;
  deviceParams.value = deviceParamsConfig[node.data.type] || [];

  Object.keys(deviceForm).forEach(key => delete deviceForm[key]);
  deviceParams.value.forEach(param => {
    deviceForm[param.key] = node.data.params[param.key];
  });

  modalVisible.value = true;
};

// 模态框确定
const handleModalOk = () => {
  deviceParams.value.forEach(param => {
    selectedDevice.value.data.params[param.key] = deviceForm[param.key];
  });

  updateNodeParamsDisplay(selectedDevice.value);
  modalVisible.value = false;
};

// 模态框取消
const handleModalCancel = () => {
  modalVisible.value = false;
};

// 获取鼠标位置的节点（兼容X6 2.18.1版本）
const getNodeAtPoint = (clientX, clientY) => {
  if (!graph.value) return null;

  const point = graph.value.clientToLocal(clientX, clientY);
  const nodes = graph.value.getNodes();

  // 使用getBBox判断节点是否包含点
  for (let i = nodes.length - 1; i >= 0; i--) {
    const node = nodes[i];
    const bbox = node.getBBox();
    if (bbox.containsPoint(point)) {
      return node;
    }
  }

  return null;
};

// 初始化连线功能
const initConnection = () => {
  const arrowCursor = document.createElement('div');
  arrowCursor.style.position = 'absolute';
  arrowCursor.style.width = '20px';
  arrowCursor.style.height = '20px';
  arrowCursor.style.backgroundImage = 'url("")';
  arrowCursor.style.backgroundSize = 'contain';
  arrowCursor.style.pointerEvents = 'none';
  arrowCursor.style.zIndex = '1000';
  arrowCursor.style.display = 'none';
  document.body.appendChild(arrowCursor);

  const handleMouseMove = (e) => {
    if (connectingState.isConnecting) {
      arrowCursor.style.display = 'block';
      arrowCursor.style.left = `${e.clientX + 10}px`;
      arrowCursor.style.top = `${e.clientY + 10}px`;

      if (connectingState.edge) {
        const point = graph.value.clientToLocal(e.clientX, e.clientY);
        connectingState.edge.setTarget(point);
      }
    }
  };

  const handleMouseDown = (e) => {
    if (e.button === 2 && !connectingState.isConnecting) {
      const node = getNodeAtPoint(e.clientX, e.clientY);
      if (node) {
        startConnection(node, e.clientX, e.clientY);
      }
    }
  };

  const handleMouseUp = (e) => {
    if (e.button === 2 && connectingState.isConnecting) {
      const node = getNodeAtPoint(e.clientX, e.clientY);
      if (node && node.id !== connectingState.sourceNode.id) {
        completeConnection(node);
      } else {
        cancelConnection();
      }
    }
  };

  window.addEventListener('mousemove', handleMouseMove);
  window.addEventListener('mousedown', handleMouseDown);
  window.addEventListener('mouseup', handleMouseUp);

  onBeforeUnmount(() => {
    window.removeEventListener('mousemove', handleMouseMove);
    window.removeEventListener('mousedown', handleMouseDown);
    window.removeEventListener('mouseup', handleMouseUp);
    document.body.removeChild(arrowCursor);
  });
};

// 开始创建连线
const startConnection = (sourceNode, clientX, clientY) => {
  connectingState.isConnecting = true;
  connectingState.sourceNode = sourceNode;

  const point = graph.value.clientToLocal(clientX, clientY);
  connectingState.edge = graph.value.addEdge({
    shape: 'device-connection', // 直接使用注册的形状
    source: { cell: sourceNode.id },
    target: point,
    attrs: {
      line: {
        stroke: '#1890ff',
        strokeWidth: 2,
        targetMarker: {
          name: 'block',
          width: 12,
          height: 8,
        },
        strokeDasharray: '5 5',
      }
    },
    zIndex: 0,
  });
};

// 完成连线
const completeConnection = (targetNode) => {
  if (connectingState.edge) {
    // 移除临时连线
    graph.value.removeCell(connectingState.edge);

    // 创建正式连线
    const edge = graph.value.addEdge({
      shape: 'device-connection',
      source: { cell: connectingState.sourceNode.id },
      target: { cell: targetNode.id },
      attrs: {
        line: {
          stroke: '#1890ff',
          strokeWidth: 2,
          targetMarker: {
            name: 'block',
            width: 12,
            height: 8,
          },
        }
      },
      data: {
        type: 'connection',
        from: connectingState.sourceNode.data.label,
        to: targetNode.data.label,
        createdAt: new Date().toISOString()
      },
      zIndex: 0,
    });
  }

  resetConnectionState();
};

// 取消连线
const cancelConnection = () => {
  if (connectingState.edge) {
    graph.value.removeCell(connectingState.edge);
  }
  resetConnectionState();
};

// 重置连线状态
const resetConnectionState = () => {
  connectingState.isConnecting = false;
  connectingState.sourceNode = null;
  connectingState.edge = null;
  document.querySelectorAll('.arrow-cursor').forEach(el => el.style.display = 'none');
};

onMounted(() => {
  graph.value = new Graph({
    panning: { enabled: true, modifiers: 'space', eventTypes: "leftMouseDown" },
    scaling: { min: 0.05, max: 1 },
    mousewheel: {
      enabled: true,
      modifiers: ['ctrl', 'meta'],
      guard: (e) => !e.altKey
    },
    grid: {
      size: 10,
      visible: true,
      args: { color: '#a0a0a0', thickness: 1 }
    },
    container: container.value,
    connecting: { anchor: 'orth' },
  });

  // 节点点击事件
  graph.value.on('node:click', ({ node }) => {
    showEditModal(node);
  });

  // 初始化连线功能
  initConnection();

  // 添加示例节点
  const sampleNode1 = createDeviceNode(graph.value,
    { label: '示例电表', type: 'meter' },
    { x: 100, y: 100 }
  );
  const sampleNode2 = createDeviceNode(graph.value,
    { label: '示例PCS', type: 'pcs' },
    { x: 300, y: 100 }
  );
  graph.value.addNode([sampleNode1, sampleNode2]);
});
</script>

<style scoped>
.xpage {
  height: 100vh;
  display: flex;
}

.my_container {
  flex: 1;
  height: 100%;
  border: 1px solid #d9d9d9;
  background: #f5f5f5;
}

.left_obj {
  background-color: #fff;
  width: 120px;
  padding: 10px;
  border-right: 1px solid #d9d9d9;
}

.draggable-item {
  background-color: #e0d6d6;
  color: #333;
  text-align: center;
  border-radius: 10px;
  cursor: move;
  margin-bottom: 10px;
  user-select: none;
  transition: all 0.3s;
  border: 1px solid gray;
  padding:10px 10px;
  width:100%;
}

.draggable-item:hover {
  background-color: #40a9ff;
  transform: translateX(5px);
}
</style>

<style>
/* 全局连线样式 */
.x6-edge {
  stroke: #1890ff;
  stroke-width: 2;
}

.x6-edge:hover {
  stroke: #ff4d4f;
  stroke-width: 3;
}

.x6-edge .x6-edge-path {
  stroke: inherit;
  stroke-width: inherit;
}
</style>